#ifndef __TDP2_GLFUNCTIONS_HPP__
#define __TDP2_GLFUNCTIONS_HPP__

#include "../mesa/gl.h"
#include "../mesa/glext.h"

namespace TDP
{
	namespace Rendering
	{
		struct IGLInitializer;

		// PFn types not defined by GL.h
		typedef void (APIENTRYP PFNGLBEGINPROC) ( GLenum mode );
		typedef void (APIENTRYP PFNGLENDPROC) ( void );
		typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGPROC) ( GLenum name );
		typedef void (APIENTRYP PFNGLGETINTEGERVPROC) ( GLenum pname, GLint *params );
		typedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERIVPROC) ( GLenum target,
			GLint level, GLenum pname, GLint *params);
		typedef void (APIENTRYP PFNGLGENTEXTURESPROC) ( GLsizei n, GLuint *textures );
		typedef void (APIENTRYP PFNGLDELETETEXTURESPROC) ( GLsizei n, const GLuint *textures);
		typedef void (APIENTRYP PFNGLBINDTEXTUREPROC) ( GLenum target, GLuint texture );
		typedef void (APIENTRYP PFNGLTEXIMAGE2DPROC) ( GLenum target, GLint level,
			GLint internalFormat, GLsizei width, GLsizei height, GLint border,
			GLenum format, GLenum type, const GLvoid *pixels );
		typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) ( GLenum target, GLint level,
			GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border,
			GLenum format, GLenum type, const GLvoid *pixels );
		typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DPROC) ( GLenum target, GLint level,
			GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format,
			GLenum type, const GLvoid *data);
		typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) ( GLenum target, GLint level,
			GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
			GLenum format, GLenum type, const GLvoid *data);
		typedef void (APIENTRYP PFNGLPIXELSTOREIPROC) ( GLenum pname, GLint param );

		typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) ( GLenum target, GLint level, GLvoid *img );
		typedef GLenum (APIENTRYP PFNGLGETERRORPROC) ( void );
		typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC) ( GLenum target, GLenum pname, GLint param );
		typedef void (APIENTRYP PFNGLGETTEXPARAMETERIV) ( GLenum target, GLenum pname, GLint *params );

		typedef void (APIENTRYP PFNGLENABLEPROC) ( GLenum cap );
		typedef void (APIENTRYP PFNGLDISABLEPROC) ( GLenum cap );

		typedef void (APIENTRYP PFNGLENABLECLIENTSTATEPROC) ( GLenum cap );
		typedef void (APIENTRYP PFNGLDISABLECLIENTSTATEPROC) ( GLenum cap );

		typedef void (APIENTRYP PFNGLVERTEXPOINTERPROC) ( GLint size, GLenum type,
										   GLsizei stride, const GLvoid *ptr );
		typedef void (APIENTRYP PFNGLNORMALPOINTERPROC) ( GLenum type, GLsizei stride,
										   const GLvoid *ptr );
		typedef void (APIENTRYP PFNGLCOLORPOINTERPROC) ( GLint size, GLenum type,
										  GLsizei stride, const GLvoid *ptr );
		typedef void (APIENTRYP PFNGLINDEXPOINTERPROC) ( GLenum type, GLsizei stride,
										  const GLvoid *ptr );
		typedef void (APIENTRYP PFNGLTEXCOORDPOINTERPROC) ( GLint size, GLenum type,
											 GLsizei stride, const GLvoid *ptr );

		typedef void (APIENTRYP PFNGLDEPTHMASKPROC) ( GLboolean flag );
		typedef void (APIENTRYP PFNGLDEPTHFUNCPROC) ( GLenum func );
		typedef void (APIENTRYP PFNGLCOLORMASKPROC) ( GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha );

		typedef void (APIENTRYP PFNGLBLENDFUNCPROC) ( GLenum sfactor, GLenum dfactor );

		typedef void (APIENTRYP PFNGLCLEARDEPTHPROC) ( GLclampd depth );
		typedef void (APIENTRYP PFNGLCLEARPROC) ( GLbitfield mask );
		typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC) ( GLenum target, GLint level,
											   GLint xoffset, GLint yoffset,
											   GLint x, GLint y,
											   GLsizei width, GLsizei height );
		typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DPROC)( GLenum target, GLint level,
											GLenum internalformat,
											GLint x, GLint y,
											GLsizei width, GLsizei height,
											GLint border );
		typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC)(GLenum texture);

		struct GLFunctions
		{
			bool Initialize(const IGLInitializer *i, const char **blameProc);

			PFNGLBEGINPROC Begin;
			PFNGLENDPROC End;
			PFNGLGETSTRINGPROC GetString;
			PFNGLGETINTEGERVPROC GetIntegerv;
			PFNGLCOMPRESSEDTEXIMAGE2DARBPROC CompressedTexImage2DARB;
			PFNGLCOMPRESSEDTEXIMAGE3DARBPROC CompressedTexImage3DARB;
			PFNGLGETTEXLEVELPARAMETERIVPROC GetTexLevelParameteriv;
			PFNGLGENTEXTURESPROC GenTextures;
			PFNGLDELETETEXTURESPROC DeleteTextures;
			PFNGLBINDTEXTUREPROC BindTexture;
			PFNGLTEXIMAGE2DPROC TexImage2D;
			PFNGLTEXIMAGE3DPROC TexImage3D;
			PFNGLTEXSUBIMAGE2DPROC TexSubImage2D;
			PFNGLTEXSUBIMAGE3DPROC TexSubImage3D;
			PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC CompressedTexSubImage2DARB;
			PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC CompressedTexSubImage3DARB;

			PFNGLPIXELSTOREIPROC PixelStorei;

			PFNGLGETCOMPRESSEDTEXIMAGEARBPROC GetCompressedTexImageARB;
			PFNGLGETERRORPROC GetError;
			PFNGLTEXPARAMETERIPROC TexParameteri;
			PFNGLGETTEXPARAMETERIV GetTexParameteriv;

			PFNGLENABLEPROC Enable;
			PFNGLDISABLEPROC Disable;
			PFNGLENABLECLIENTSTATEPROC EnableClientState;
			PFNGLDISABLECLIENTSTATEPROC DisableClientState;

			PFNGLACTIVETEXTUREPROC ActiveTexture;
			PFNGLCLIENTACTIVETEXTUREPROC ClientActiveTexture;

			PFNGLBINDBUFFERARBPROC BindBufferARB;
			PFNGLDELETEBUFFERSARBPROC DeleteBuffersARB;
			PFNGLGENBUFFERSARBPROC GenBuffersARB;
			PFNGLISBUFFERARBPROC IsBufferARB;
			PFNGLBUFFERDATAARBPROC BufferDataARB;
			PFNGLBUFFERSUBDATAARBPROC BufferSubDataARB;
			PFNGLGETBUFFERSUBDATAARBPROC GetBufferSubDataARB;
			PFNGLMAPBUFFERARBPROC MapBufferARB;
			PFNGLUNMAPBUFFERARBPROC UnmapBufferARB;
			PFNGLGETBUFFERPARAMETERIVARBPROC GetBufferParameterivARB;
			PFNGLGETBUFFERPOINTERVARBPROC GetBufferPointervARB;

			PFNGLPROGRAMSTRINGARBPROC ProgramStringARB;
			PFNGLBINDPROGRAMARBPROC BindProgramARB;
			PFNGLDELETEPROGRAMSARBPROC DeleteProgramsARB;
			PFNGLGENPROGRAMSARBPROC GenProgramsARB;
			PFNGLPROGRAMLOCALPARAMETER4FVARBPROC ProgramLocalParameter4fvARB;

			PFNGLVERTEXPOINTERPROC VertexPointer;
			PFNGLNORMALPOINTERPROC NormalPointer;
			PFNGLCOLORPOINTERPROC ColorPointer;
			PFNGLINDEXPOINTERPROC IndexPointer;
			PFNGLVERTEXATTRIBPOINTERPROC VertexAttribPointer;

			PFNGLDRAWRANGEELEMENTSPROC DrawRangeElements;

			PFNGLDEPTHMASKPROC DepthMask;
			PFNGLDEPTHFUNCPROC DepthFunc;
			PFNGLCOLORMASKPROC ColorMask;

			PFNGLBLENDFUNCPROC BlendFunc;

			PFNGLCREATEPROGRAMOBJECTARBPROC CreateProgramObjectARB;
			PFNGLCREATESHADEROBJECTARBPROC CreateShaderObjectARB;
			PFNGLCOMPILESHADERARBPROC CompileShaderARB;
			PFNGLSHADERSOURCEARBPROC ShaderSourceARB;
			PFNGLGETUNIFORMLOCATIONARBPROC GetUniformLocationARB;
			PFNGLGETATTRIBLOCATIONARBPROC GetAttribLocationARB;
			PFNGLBINDATTRIBLOCATIONARBPROC BindAttribLocationARB;
			PFNGLENABLEVERTEXATTRIBARRAYARBPROC EnableVertexAttribArrayARB;
			PFNGLDISABLEVERTEXATTRIBARRAYARBPROC DisableVertexAttribArrayARB;
			PFNGLATTACHOBJECTARBPROC AttachObjectARB;
			PFNGLLINKPROGRAMARBPROC LinkProgramARB;
			PFNGLUSEPROGRAMOBJECTARBPROC UseProgramObjectARB;
			PFNGLDELETEOBJECTARBPROC DeleteObjectARB;

			PFNGLGETOBJECTPARAMETERIVARBPROC GetObjectParameterivARB;
			PFNGLGETINFOLOGARBPROC GetInfoLogARB;

			PFNGLUNIFORM1FVARBPROC Uniform1fvARB;
			PFNGLUNIFORM2FVARBPROC Uniform2fvARB;
			PFNGLUNIFORM3FVARBPROC Uniform3fvARB;
			PFNGLUNIFORM4FVARBPROC Uniform4fvARB;

			PFNGLUNIFORMMATRIX2FVARBPROC UniformMatrix2fvARB;
			PFNGLUNIFORMMATRIX3FVARBPROC UniformMatrix3fvARB;
			PFNGLUNIFORMMATRIX4FVARBPROC UniformMatrix4fvARB;

			PFNGLUNIFORM1IVARBPROC Uniform1ivARB;
			PFNGLUNIFORM2IVARBPROC Uniform2ivARB;
			PFNGLUNIFORM3IVARBPROC Uniform3ivARB;
			PFNGLUNIFORM4IVARBPROC Uniform4ivARB;

			PFNGLCLEARDEPTHPROC ClearDepth;
			PFNGLCLEARPROC Clear;
			PFNGLCOPYTEXSUBIMAGE2DPROC CopyTexSubImage2D;
			PFNGLCOPYTEXIMAGE2DPROC CopyTexImage2D;
		};
	}
};


#endif
